package no.ntnu.idi.deid.patternmatching.search.regularexpression;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import no.ntnu.idi.deid.config.FilePaths;
import no.ntnu.idi.deid.documentunits.Token;
import no.ntnu.idi.deid.searchresultunits.CategoryTag;

public class RegularExpressionDatabase  extends ArrayList<PatternType>{
	
	
	private static final long serialVersionUID = 1L;
	public static final String TYPE_DIVISOR = "#CATEGORYTAG";
	public static final String FILE_LOCATION = FilePaths.getRegexDatabaseFilePath();
	
	private static RegularExpressionDatabase instance = null;
	
	private RegularExpressionDatabase() {
		genereateRegularExpressionDatabase();
	}
	
	/**
	 * Singelton pattern
	 * @return returns the singelton instance
	 */
	public static RegularExpressionDatabase getInstance() {
		if (instance == null) {
			instance = new RegularExpressionDatabase();
		}
		return instance;
	}
	
	private Pattern getDatabaseItemPattern(int i) {
		return get(i).getPattern();
	}
	public CategoryTag getDatabaseCategoryTag(int i) {
		return get(i).getCategoryTag();
	}
	
	/**
	 * 
	 * @param patternString
	 * @return
	 * @throws PatternSyntaxException
	 */
	private PatternType createPatternTypeFromString(String patternString)
			throws PatternSyntaxException {
		int indexOfDivisor = patternString.indexOf(TYPE_DIVISOR);
		String categoryTag = patternString.substring(
				indexOfDivisor + TYPE_DIVISOR.length() + 1).trim();
		String pattern = patternString.substring(0, indexOfDivisor).trim();
		return new PatternType(Pattern.compile(pattern),
				CategoryTag.getCategoryTagByString(categoryTag));
	}

	private void genereateRegularExpressionDatabase() {
		File file = new File(FILE_LOCATION);
		if (isValidFile(file)) {
			try {
				FileInputStream fstream = new FileInputStream(file);
				DataInputStream in = new DataInputStream(fstream);
				BufferedReader br = new BufferedReader(
						new InputStreamReader(in));
				String strLine;
				while ((strLine = br.readLine()) != null) {
					try {
								add(createPatternTypeFromString(strLine));
					} catch (PatternSyntaxException e) {
						System.err
								.println("Filen inneholder ugyldig regex-syntax");
						e.printStackTrace();
					}
				}
				in.close();
			} catch (Exception e) {
				System.err.println("FEIL: Feil under lesing av fil");
				e.printStackTrace();
			}
		}
	}
	
	public Set<CategoryTag> search(Token tok) {
		Set<CategoryTag> returnSet = new HashSet<CategoryTag>();
		if(tok.getStripped().equals("03.07.2008")) {
			System.out.println();
		}
		for (int i = 0; i < size(); i++) {
			Pattern pattern = getDatabaseItemPattern(i);
			Matcher matcher = pattern.matcher(tok.getStripped());
			matcher.reset();
			if (matcher.matches()) {
				returnSet.add(getDatabaseCategoryTag(i));
			}
		}
		return returnSet;
	}
	

	/**
	 * 
	 * @param file
	 * @return
	 */
	private boolean isValidFile(File file) {
		if (file.getName().endsWith(".txt")) {
			return true;
		} else {
			return false;
		}
	}
}
